package com.alan.thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

/**
 * Java 7在java.util.concurrent包下加入了支持fork/join框架的RecursiveTask，forkjoinpool
 * 例子，去计算从start到end的连续数字的和：
 * 1）执行任务的类要继承RecursiveTask类
 * 2）定义一个compute方法，将要算的数分成两组，再分别调用compute方法去算。 运用了递归算法
 * 3）定义一个ForkJoinPool去执行任务， submit方法返还一个Future类， 通过future.get()去获取任务结果
 * Created by Alan on 17-10-9
 */
public class J7ForkJoin extends RecursiveTask<Integer> {
    private static final int THRESHOLD = 5;
    private int beginning;
    private int ending;

    public J7ForkJoin(int beginning, int ending) {
        super();
        this.beginning = beginning;
        this.ending = ending;
    }

    //override compute
    @Override
    protected Integer compute() {
        //check if still need fork
        int sum = 0;
        boolean canCompute = (ending - beginning) <= THRESHOLD;
        if (canCompute) {
            //no need
            System.out.println("no need fork, ThreadID=" + Thread.currentThread().getId());
            System.out.println("no need fork, beginning=" + this.beginning);
            System.out.println("no need fork, ending=" + this.ending);
            for (int i = beginning; i <= ending; ++i) {
                sum += i;
            }
            return sum;
        } else {
            //need
            int interim = (this.ending + this.beginning) / 2;
            //5+1 /2 =3 1-3
            //6+1 /2 =3 1-3
            System.out.println("need fork, ThreadID=" + Thread.currentThread().getId());
            System.out.println("need fork, interim=" + interim);
            J7ForkJoin leftTask = new J7ForkJoin(this.beginning, interim);
            J7ForkJoin rightTask = new J7ForkJoin(interim + 1, this.ending);
            //.fork
            leftTask.fork();
            rightTask.fork();
            //get reuslt
            int leftResult = leftTask.join();
            int rightResult = rightTask.join();
            sum = leftResult + rightResult;
            return sum;
        }
    }

    public static void main(String[] args) {
        ForkJoinPool FJPool = new ForkJoinPool();
        J7ForkJoin task = new J7ForkJoin(1, 20);
        Future<Integer> result = FJPool.submit(task);
        try {
            System.out.println("main result=" + result.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void mainJava8(String[] args) {
        ForkJoinPool FJPool = new ForkJoinPool();
        Future<Integer> result = FJPool.submit(()->{
            Thread.sleep(8000);
            return new Integer(10);
        });
        try {
            System.out.println("main result=" + result.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

}
